package top.saodisheng.utils;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * description:
 *
 * @author saodisheng
 * @date 2022/8/1
 */
public class JacksonUtil {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    private JacksonUtil() {
        OBJECT_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        OBJECT_MAPPER.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }

    public static ObjectMapper getInstance() {
        return OBJECT_MAPPER;
    }

    public static String toJson(Object obj) throws IOException {
        return OBJECT_MAPPER.writeValueAsString(obj);
    }

    public static String toJson(Object obj, String defaultValue) {
        try {
            return toJson(obj);
        } catch (IOException var3) {
            return defaultValue;
        }
    }

    public static String toJsonIgnoreNull(Object obj) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(Include.NON_NULL);
        return mapper.writeValueAsString(obj);
    }

    public static <T> T json2pojo(String jsonString, Class<T> clazz) throws IOException {
        OBJECT_MAPPER.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        return OBJECT_MAPPER.readValue(jsonString, clazz);
    }

    public static Map json2map(String jsonString) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(Include.NON_NULL);
        return mapper.readValue(jsonString, Map.class);
    }

    public static <T> Map<String, T> json2map(String jsonString, Class<T> clazz) throws IOException {
        Map<String, Object> map = (Map<String, Object>) OBJECT_MAPPER.readValue(jsonString, new TypeReference<Map>() {
        });
        Map<String, T> result = new HashMap<>();
        Iterator var5 = map.entrySet().iterator();

        while (var5.hasNext()) {
            Entry<String, Object> entry = (Entry<String, Object>) var5.next();
            result.put(entry.getKey(), map2pojo((Map<String, Object>) entry.getValue(), clazz));
        }

        return result;
    }

    public static Map<String, Object> json2mapDeeply(String json) throws Exception {
        return json2MapRecursion(json, OBJECT_MAPPER);
    }

    private static List<Object> json2ListRecursion(String json, ObjectMapper mapper) throws Exception {
        if (json == null) {
            return null;
        } else {
            List<Object> list = (List) mapper.readValue(json, List.class);
            Iterator<Object> var4 = list.iterator();

            while (var4.hasNext()) {
                Object obj = var4.next();
                if (obj instanceof String) {
                    String str = (String) obj;
                    if (str.startsWith("[")) {
                        json2ListRecursion(str, mapper);
                    } else if (obj.toString().startsWith("{")) {
                        json2MapRecursion(str, mapper);
                    }
                }
            }

            return list;
        }
    }

    private static Map<String, Object> json2MapRecursion(String json, ObjectMapper mapper) throws Exception {
        if (json == null) {
            return null;
        } else {
            Map<String, Object> map = (Map<String, Object>) mapper.readValue(json, Map.class);
            Iterator var4 = map.entrySet().iterator();

            while (var4.hasNext()) {
                Entry<String, Object> entry = (Entry<String, Object>) var4.next();
                Object obj = entry.getValue();
                if (obj instanceof String) {
                    String str = (String) obj;
                    if (str.startsWith("[")) {
                        List<?> list = json2ListRecursion(str, mapper);
                        map.put((String) entry.getKey(), list);
                    } else if (str.startsWith("{")) {
                        Map<String, Object> mapRecursion = json2MapRecursion(str, mapper);
                        map.put(entry.getKey(), mapRecursion);
                    }
                }
            }

            return map;
        }
    }

    public static List<Map<String, Object>> json2list(String jsonArrayStr) throws Exception {
        return (List) OBJECT_MAPPER.readValue(jsonArrayStr, new TypeReference<List<Map>>() {
        });
    }

    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    public static <T> T map2pojo(Map map, Class<T> clazz) {
        return OBJECT_MAPPER.convertValue(map, clazz);
    }

    public static String mapToJson(Map map) {
        try {
            return OBJECT_MAPPER.writeValueAsString(map);
        } catch (Exception var2) {
            var2.printStackTrace();
            return "";
        }
    }

    public static <T> T obj2pojo(Object obj, Class<T> clazz) {
        return OBJECT_MAPPER.convertValue(obj, clazz);
    }
}

